subprocess 您所在的位置:网站首页 linux python执行 subprocess

subprocess

2024-07-10 18:40| 来源: 网络整理| 查看: 265

在一个新的进程中执行子程序。 在 POSIX 上,该类会使用类似于 os.execvpe() 的行为来执行子程序。 在 Windows 上,该类会使用 Windows CreateProcess() 函数。 Popen 的参数如下。

args 应当是一个程序参数的序列或者是一个单独的字符串或 path-like object。 默认情况下,如果 args 是序列则要运行的程序为 args 中的第一项。 如果 args 是字符串,则其解读依赖于具体平台,如下所述。 请查看 shell 和 executable 参数了解其与默认行为的其他差异。 除非另有说明,否则推荐以序列形式传入 args。

警告

为了最大化可靠性,请使用可执行文件的完整限定路径。 要在 PATH 中搜索一个非限定名称,请使用 shutil.which()。 在所有平台上,传入 sys.executable 是再次启动当前 Python 解释器的推荐方式,并请使用 -m 命令行格式来启动已安装的模块。

对 executable (或 args 的第一项) 路径的解析方式依赖于具体平台。 对于 POSIX,请参阅 os.execvpe(),并要注意当解析或搜索可执行文件路径时,cwd 会覆盖当前工作目录而 env 可以覆盖 PATH 环境变量。 对于 Windows,请参阅 lpApplicationName 的文档以及 lpCommandLine 形参 (传给 WinAPI CreateProcess),并要注意当解析或搜索可执行文件路径时如果传入 shell=False,则 cwd 不会覆盖当前工作目录而 env 无法覆盖 PATH 环境变量。 使用完整路径可避免所有这些变化情况。

向外部函数传入序列形式参数的一个例子如下:

Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."])

在 POSIX,如果 args 是一个字符串,此字符串被作为将被执行的程序的命名或路径解释。但是,只有在不传递任何参数给程序的情况下才能这么做。

备注

将 shell 命令拆分为参数序列的方式可能并不很直观,特别是在复杂的情况下。 shlex.split() 可以演示如何确定 args 适当的拆分形式:

>>> import shlex, subprocess >>> command_line = input() /bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'" >>> args = shlex.split(command_line) >>> print(args) ['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"] >>> p = subprocess.Popen(args) # Success!

特别注意,由 shell 中的空格分隔的选项(例如 -input)和参数(例如 eggs.txt )位于分开的列表元素中,而在需要时使用引号或反斜杠转义的参数在 shell (例如包含空格的文件名或上面显示的 echo 命令)是单独的列表元素。

在 Windows,如果 args 是一个序列,他将通过一个在 在 Windows 上将参数列表转换为一个字符串 描述的方式被转换为一个字符串。这是因为底层的 CreateProcess() 只处理字符串。

在 3.6 版本发生变更: 在 POSIX 上如果 shell 为 False 并且序列包含路径类对象则 args 形参可以接受一个 path-like object。

在 3.8 版本发生变更: 如果在Windows 上 shell 为 False 并且序列包含字节串和路径类对象则 args 形参可以接受一个 path-like object。

参数 shell (默认为 False)指定是否使用 shell 执行程序。如果 shell 为 True,更推荐将 args 作为字符串传递而非序列。

在 POSIX,当 shell=True, shell 默认为 /bin/sh。如果 args 是一个字符串,此字符串指定将通过 shell 执行的命令。这意味着字符串的格式必须和在命令提示符中所输入的完全相同。这包括,例如,引号和反斜杠转义包含空格的文件名。如果 args 是一个序列,第一项指定了命令,另外的项目将作为传递给 shell (而非命令) 的参数对待。也就是说, Popen 等同于:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

在 Windows,使用 shell=True,环境变量 COMSPEC 指定了默认 shell。在 Windows 你唯一需要指定 shell=True 的情况是你想要执行内置在 shell 中的命令(例如 dir 或者 copy)。在运行一个批处理文件或者基于控制台的可执行文件时,不需要 shell=True。

备注

在使用 shell=True 之前, 请阅读 Security Considerations 段落。

bufsize 将在 open() 函数创建了 stdin/stdout/stderr 管道文件对象时作为对应的参数供应:

0 表示不使用缓冲区(读取与写入是一个系统调用并且可以返回短内容)

1 表示带有行缓冲(仅在 text=True 或 universal_newlines=True 时有用)

任何其他正值表示使用一个约为对应大小的缓冲区

负的 bufsize (默认)表示使用系统默认的 io.DEFAULT_BUFFER_SIZE。

在 3.3.1 版本发生变更: bufsize 现在默认为 -1 表示启用缓冲以符合大多数代码所期望的行为。 在 Python 3.2.4 和 3.3.1 之前的版本中它错误地将默认值设为 0 即无缓冲并且允许短读取。 这是无意的失误并且与大多数代码所期望的 Python 2 的行为不一致。

executable 参数指定一个要执行的替换程序。这很少需要。当 shell=True, executable 替换 args 指定运行的程序。但是,原始的 args 仍然被传递给程序。大多数程序将被 args 指定的程序作为命令名对待,这可以与实际运行的程序不同。在 POSIX, args 名作为实际调用程序中可执行文件的显示名称,例如 ps。如果 shell=True,在 POSIX, executable 参数指定用于替换默认 shell /bin/sh 的 shell。

在 3.6 版本发生变更: 在POSIX 上 executable 形参可以接受一个 path-like object。

在 3.8 版本发生变更: 在Windows 上 executable 形参可以接受一个字节串和 path-like object。

在 3.12 版本发生变更: 针对 shell=True 改变的 Windows shell 搜索顺序。 当前目录和 %PATH% 会被替换为 %COMSPEC% 和 %SystemRoot%\System32\cmd.exe。 因此,在当前目录中投放一个命名为 cmd.exe 的恶意程序不会再起作用。

stdin, stdout 和 stderr 分别指定被执行程序的标准输入、标准输出和标准错误文件句柄。 合法的值包括 None, PIPE, DEVNULL, 现在的文件描述符(一个正整数),现存的具有合法文件描述符的 file object。 当使用默认设置 None 时,将不会进行任何重定向。 PIPE 表示应当新建一个连接子进程的管道。 DEVNULL 表示将使用特殊文件 os.devnull。 此外,stderr 还可以为 STDOUT,这表示来自子进程的 stderr 数据应当被捕获到与 stdout 相同的文件句柄中。

如果 preexec_fn 被设为一个可调用对象,此对象将在子进程刚创建时被调用。(仅 POSIX)

警告

preexec_fn 形参在应用程序中存在多线程时是不安全的。 子进程在 exec 被调用之前可能会死锁。

备注

如果你需要为子进程修改环境请使用 env 形参而不要在 preexec_fn 中操作。 start_new_session 和 process_group 形参应当代替使用 preexec_fn 的代码来在子进程中调用 os.setsid() 或 os.setpgid()。

在 3.8 版本发生变更: preexec_fn 形参在子解释器中已不再受支持。 在子解释器中使用此形参将引发 RuntimeError。 这个新限制可能会影响部署在 mod_wsgi, uWSGI 和其他嵌入式环境中的应用。

如果 close_fds 为真值,则除 0, 1 和 2 之外的所有文件描述符都将在子进程执行前被关闭。 而当 close_fds 为假值时,文件描述符将遵循它们的可继承旗标,如 文件描述符的继承 所描述的。

在 Windows,如果 close_fds 为真, 则子进程不会继承任何句柄,除非在 STARTUPINFO.IpAttributeList 的 handle_list 的键中显式传递,或者通过标准句柄重定向传递。

在 3.2 版本发生变更: close_fds 的默认值已经从 False 修改为上述值。

在 3.7 版本发生变更: 在 Windows,当重定向标准句柄时 close_fds 的默认值从 False 变为 True。现在重定向标准句柄时有可能设置 close_fds 为 True。(标准句柄指三个 stdio 的句柄)

pass_fds 是一个可选的在父子进程间保持打开的文件描述符序列。提供任何 pass_fds 将强制 close_fds 为 True。(仅 POSIX)

在 3.2 版本发生变更: 加入了 pass_fds 形参。

如果 cwd 不为 None,此函数在执行子进程前会将当前工作目录改为 cwd。 cwd 可以是一个字符串、字节串或 路径类对象。 在 POSIX 上,如果可执行文件路径为相对路径则此函数会相对于 cwd 来查找 executable (或 args 的第一项)。

在 3.6 版本发生变更: 在 POSIX 上 cwd 形参接受一个 path-like object。

在 3.7 版本发生变更: 在 Windows 上 cwd 形参接受一个 path-like object。

在 3.8 版本发生变更: 在 Windows 上 cwd 形参接受一个字节串对象。

 如果 restore_signals 为 true(默认值),则 Python 设置为 SIG_IGN 的所有信号将在 exec 之前的子进程中恢复为 SIG_DFL。目前,这包括 SIGPIPE ,SIGXFZ 和 SIGXFSZ 信号。 (仅 POSIX)

在 3.2 版本发生变更: restore_signals 被加入。

如果 start_new_session 为真值则 setsid() 系统调用将在执行子进程之前在子进程中执行。

可用性: POSIX

在 3.2 版本发生变更: start_new_session 被添加。

如果 process_group 为非负整数,则 setpgid(0, value) 系统调用将在执行子进程之前在子进程中执行。

可用性: POSIX

在 3.11 版本发生变更: 添加了 process_group。

如果 group 不为 None,则 setregid() 系统调用将于子进程执行之前在下级进程中进行。 如果所提供的值为一个字符串,将通过 grp.getgrnam() 来查找它,并将使用 gr_gid 中的值。 如果该值为一个整数,它将被原样传递。 (POSIX 专属)

可用性: POSIX

Added in version 3.9.

如果 extra_groups 不为 None,则 setgroups() 系统调用将于子进程之前在下级进程中进行。 在 extra_groups 中提供的字符串将通过 grp.getgrnam() 来查找,并将使用 gr_gid 中的值。 整数值将被原样传递。 (POSIX 专属)

可用性: POSIX

Added in version 3.9.

如果 user 不为 None,则 setreuid() 系统调用将于子进程执行之前在下级进程中进行。 如果所提供的值为一个字符串,将通过 pwd.getpwnam() 来查找它,并将使用 pw_uid 中的值。 如果该值为一个整数,它将被原样传递。 (POSIX 专属)

可用性: POSIX

Added in version 3.9.

如果 umask 不为负值,则 umask() 系统调用将在子进程执行之前在下级进程中进行。

可用性: POSIX

Added in version 3.9.

如果 env 不为 None,则它必须是一个为新进程定义环境变量的映射;它们将顶替继承当前环境的默认行为被使用。 这个映射在任何平台上均可以是字符串到字符串的映射或者在 POSIX 平台上也可以是字节串到字节串的映射,就像是 os.environ 或者 os.environb。

备注

如果指定, env 必须提供所有被子进程需求的变量。在 Windows,为了运行一个 side-by-side assembly ,指定的 env 必须 包含一个有效的 SystemRoot。

如果指定了 encoding 或 errors,或者如果 text 为真值,则文件对象 stdin, stdout 和 stderr 将使用指定的 encoding 和 errors 以文本模式打开,就如上文 常用参数 中所描述的。 universal_newlines 参数等同于 text 且是出于下向兼容性考虑而提供的。 在默认情况下,文件对象将以二进制模式打开。

Added in version 3.6: encoding 和 errors 被添加。

Added in version 3.7: text 作为 universal_newlines 的一个更具可读性的别名被添加。

如果给出,startupinfo 将是一个 STARTUPINFO 对象,它会被传递给下层的 CreateProcess 函数。

如果给出,creationflags 可以是下列旗标中的一个或多个:

CREATE_NEW_CONSOLE

CREATE_NEW_PROCESS_GROUP

ABOVE_NORMAL_PRIORITY_CLASS

BELOW_NORMAL_PRIORITY_CLASS

HIGH_PRIORITY_CLASS

IDLE_PRIORITY_CLASS

NORMAL_PRIORITY_CLASS

REALTIME_PRIORITY_CLASS

CREATE_NO_WINDOW

DETACHED_PROCESS

CREATE_DEFAULT_ERROR_MODE

CREATE_BREAKAWAY_FROM_JOB

当 PIPE 被用作 stdin, stdout 或 stderr 时 pipesize 可被用于改变管道的大小。 管道的大小仅会在受支持的平台上被改变(当撰写本文档时只有 Linux 支持)。 其他平台将忽略此形参。

在 3.10 版本发生变更: 增加了 pipesize 形参。

Popen 对象支持通过 with 语句作为上下文管理器,在退出时关闭文件描述符并等待进程:

with Popen(["ifconfig"], stdout=PIPE) as proc: log.write(proc.stdout.read())

引发一个 审计事件 subprocess.Popen,附带参数 executable, args, cwd, env。

在 3.2 版本发生变更: 添加了上下文管理器支持。

在 3.6 版本发生变更: 现在,如果 Popen 析构时子进程仍然在运行,则析构器会发送一个 ResourceWarning 警告。

在 3.8 版本发生变更: 在某些情况下 Popen 可以使用 os.posix_spawn() 以获得更好的性能。在适用于 Linux 的 Windows 子系统和 QEMU 用户模拟器上,使用 os.posix_spawn() 的 Popen 构造器不再会因找不到程序等错误而引发异常,而是上下级进程失败并返回一个非零的 returncode。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有